package com.rickpan.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import com.rickpan.dto.response.TeamMessageDTO;

/**
 * 团队消息生产者
 * 负责将团队消息发送到RabbitMQ队列
 * 
 * @author 开发团队协调员
 * @since 2025-07-17
 */
@Service
@ConditionalOnProperty(name = "spring.rabbitmq.host", matchIfMissing = false)
public class TeamMessageProducer {

    private static final Logger logger = LoggerFactory.getLogger(TeamMessageProducer.class);

    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    @Autowired
    private MessageQueueService messageQueueService;

    // ==================== 团队消息发送 ====================

    /**
     * 发送团队消息到队列
     * 暂时禁用RabbitMQ发送，抛出异常让路由服务降级到Socket.IO
     *
     * @param message 团队消息DTO
     */
    public void sendTeamMessage(TeamMessageDTO message) {
        try {
            logger.info("🚀 尝试RabbitMQ发送（动态团队队列模式）: teamId={}, messageId={}",
                       message.getTeamId(), message.getId());

            // 阶段1：使用简化的团队队列模式
            // 确保团队队列存在
            messageQueueService.ensureTeamMessageQueue(message.getTeamId());

            // 发送消息到团队队列（不使用用户队列）
            messageQueueService.sendTeamMessageSimple(message.getTeamId(), message);

            logger.info("📤 团队消息已发送到队列: teamId={}, messageId={}, messageType={}",
                       message.getTeamId(), message.getId(), message.getMessageType());

        } catch (Exception e) {
            logger.error("❌ 团队消息发送失败，触发降级: teamId={}, messageId={}",
                        message.getTeamId(), message.getId(), e);
            throw new RuntimeException("消息发送失败", e);
        }
    }

    /**
     * 发送团队消息（支持不同消息类型路由）
     * 
     * @param message 团队消息DTO
     * @param useTopicRouting 是否使用主题路由
     */
    public void sendTeamMessage(TeamMessageDTO message, boolean useTopicRouting) {
        if (useTopicRouting) {
            sendTeamMessageWithTopicRouting(message);
        } else {
            sendTeamMessage(message);
        }
    }

    /**
     * 使用主题路由发送团队消息
     * 根据消息类型进行路由
     * 
     * @param message 团队消息DTO
     */
    public void sendTeamMessageWithTopicRouting(TeamMessageDTO message) {
        try {
            // 发送到主题Exchange
            messageQueueService.sendTopicMessage(
                message.getTeamId(), 
                message.getMessageType(), 
                message
            );
            
            logger.info("📤 团队消息已发送到主题队列: teamId={}, messageId={}, messageType={}", 
                       message.getTeamId(), message.getId(), message.getMessageType());
            
        } catch (Exception e) {
            logger.error("❌ 团队消息主题路由发送失败: teamId={}, messageId={}, messageType={}", 
                        message.getTeamId(), message.getId(), message.getMessageType(), e);
            throw new RuntimeException("主题消息发送失败", e);
        }
    }

    // ==================== 用户通知发送 ====================

    /**
     * 发送用户通知消息
     * 
     * @param userId 用户ID
     * @param notification 通知内容
     */
    public void sendUserNotification(Long userId, Object notification) {
        try {
            messageQueueService.sendUserNotification(userId, notification);
            
            logger.info("📤 用户通知已发送到队列: userId={}", userId);
            
        } catch (Exception e) {
            logger.error("❌ 用户通知发送失败: userId={}", userId, e);
            throw new RuntimeException("用户通知发送失败", e);
        }
    }

    // ==================== 系统广播发送 ====================

    /**
     * 发送系统广播消息
     * 
     * @param broadcastMessage 广播消息
     */
    public void sendSystemBroadcast(Object broadcastMessage) {
        try {
            messageQueueService.sendSystemBroadcast(broadcastMessage);
            
            logger.info("📤 系统广播已发送");
            
        } catch (Exception e) {
            logger.error("❌ 系统广播发送失败", e);
            throw new RuntimeException("系统广播发送失败", e);
        }
    }

    // ==================== 文件上传进度发送 ====================

    /**
     * 发送文件上传进度消息
     * 
     * @param progressMessage 进度消息
     */
    public void sendFileUploadProgress(Object progressMessage) {
        try {
            messageQueueService.sendFileUploadProgress(progressMessage);
            
            logger.debug("📤 文件上传进度已发送");
            
        } catch (Exception e) {
            logger.error("❌ 文件上传进度发送失败", e);
            // 进度消息发送失败不抛异常，避免影响主流程
        }
    }

    // ==================== 批量消息发送 ====================

    /**
     * 批量发送团队消息
     * 
     * @param messages 消息列表
     */
    public void sendTeamMessagesBatch(java.util.List<TeamMessageDTO> messages) {
        if (messages == null || messages.isEmpty()) {
            return;
        }

        int successCount = 0;
        int failCount = 0;

        for (TeamMessageDTO message : messages) {
            try {
                sendTeamMessage(message);
                successCount++;
            } catch (Exception e) {
                failCount++;
                logger.error("❌ 批量发送中的消息失败: teamId={}, messageId={}", 
                            message.getTeamId(), message.getId(), e);
            }
        }

        logger.info("📊 批量消息发送完成: 成功={}, 失败={}, 总数={}", 
                   successCount, failCount, messages.size());
    }

    // ==================== 消息重发 ====================

    /**
     * 重发失败的消息
     * 
     * @param message 要重发的消息
     * @param retryCount 重试次数
     */
    public void retryTeamMessage(TeamMessageDTO message, int retryCount) {
        try {
            // 添加重试标记
            message.setRetryCount(retryCount);
            
            sendTeamMessage(message);
            
            logger.info("🔄 消息重发成功: teamId={}, messageId={}, retryCount={}", 
                       message.getTeamId(), message.getId(), retryCount);
            
        } catch (Exception e) {
            logger.error("❌ 消息重发失败: teamId={}, messageId={}, retryCount={}", 
                        message.getTeamId(), message.getId(), retryCount, e);
            
            // 如果重试次数超过限制，记录到死信队列
            if (retryCount >= 3) {
                logger.error("💀 消息重试次数超限，将进入死信队列: teamId={}, messageId={}", 
                            message.getTeamId(), message.getId());
            }
            
            throw new RuntimeException("消息重发失败", e);
        }
    }

    // ==================== 健康检查 ====================

    /**
     * 检查消息队列连接状态
     * 
     * @return 是否连接正常
     */
    public boolean isQueueHealthy() {
        try {
            // 发送一个测试消息到系统队列
            rabbitTemplate.convertAndSend("system.health.check", "ping");
            return true;
        } catch (Exception e) {
            logger.warn("⚠️ 消息队列健康检查失败", e);
            return false;
        }
    }
}
